package com.hspedu.qqserver.service;

import com.hspedu.qqcommon.Message;
import com.hspedu.qqcommon.MessageType;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

/**
 * @Author Stringzhua
 * @Date 2024/4/11 11:33
 * description:该类对应的对象和某个客户端保持连接[通信]
 */
public class ServerConnectClientThread extends Thread {
    private Socket socket;
    private String userId;//连接到服务端的用户id

    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    public Socket getSocket() {
        return socket;
    }

    @Override
    public void run() {//这里线程处于运行状态,可以发送/接收消息
        while (true) {
            try {
                System.out.println("服务端和客户端保持通讯" + userId + "读取数据...");
                ObjectInputStream ois =
                        new ObjectInputStream(socket.getInputStream());
                Message message = (Message) ois.readObject();
                //后面会使用Message,根据message的类型做相应的业务处理
                if (message.getMessageType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
                    //客户端要在线用户列表
                    //在线用户列表形式 100 200 紫霞仙子
                    System.out.println(message.getSender() + " 要在线用户列表");
                    String onlineUser = ManageClientThreads.getOnlineUser();
                    //返回message
                    //构建一个Message对象,返回给客户端
                    Message message2 = new Message();
                    message2.setMessageType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    message2.setContent(onlineUser);
                    message2.setGetter(message.getSender());

                    //写入到数据通道,返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(message2);


                } else if (message.getMessageType().equals(MessageType.MESSAGE_COMM_MES)) {
//                    //根据message获取getter id,然后再得到对应的线程
//                    ServerConnectClientThread serverConnectClientThread =
//                            ManageClientThreads.getServerConnectClientThread(message.getGetter());
//                    //得到socket对应的对象输出流,将message对象转发给指定的客户端
//                    ObjectOutputStream oos =
//                            new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
//                    oos.writeObject(message);//转发,如果客户不在线,可以保存到数据库,实现离线留言
                    //TODO:用户登录成功后调用方法发送离线消息
                    //写一个方法 判断getter是否在线 不在线的话 将message对象存入到集合中
                    if (!OffLineMessageService.isOnline(message.getGetter())) {
                        System.out.println("该用户不在线 将在登录后接受到消息");
                        OffLineMessageService.addOfflineMap(message);
                    } else {
                        //根据message获取getterId 在得到对应的线程
                        ServerConnectClientThread serverConnectClientThread =
                                ManageClientThreads.getServerConnectClientThread(message.getGetter());
                        OutputStream outputStream = serverConnectClientThread.getSocket().getOutputStream();
                        ObjectOutputStream oos = new ObjectOutputStream(outputStream);
                        oos.writeObject(message);
                    }
                } else if (message.getMessageType().equals(MessageType.MESSAGE_TO_ALL_MES)) {
                    //需要遍历管理线程的集合,把所有线程的socket都得到,然后把message进行转发即可
                    HashMap<String, ServerConnectClientThread> hm = ManageClientThreads.getHm();

                    //遍历
                    Iterator<String> iterator = hm.keySet().iterator();
                    while (iterator.hasNext()) {
                        //取出在线用户的id
                        String onlineUserId = iterator.next().toString();
                        if (!onlineUserId.equals(message.getSender())) {
                            //排除群发消息的这个用户
                            //进行转发
                            ObjectOutputStream oos =
                                    new ObjectOutputStream(hm.get(onlineUserId).getSocket().getOutputStream());
                            oos.writeObject(message);
                        }
                    }
                } else if (message.getMessageType().equals(MessageType.MESSAGE_FILE_MES)) {
                    //根据getter id获取到对应的线程,将message对象转发
//                    ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(message.getGetter());
//                    ObjectOutputStream oos = new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
                    ObjectOutputStream oos =
                            new ObjectOutputStream(ManageClientThreads.getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
                    //直接转发
                    oos.writeObject(message);
                } else if (message.getMessageType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {//客户端退出
                    System.out.println(message.getSender() + " 退出客户端");
                    //将这个客户端对应的线程从集合中删除
                    ManageClientThreads.removeServerConnectClientThread(message.getSender());
                    socket.close();//关闭连接
                    //退出线程
                    break;
                } else {
                    System.out.println("其他类型的Message暂时不处理");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}
